package com.qq.weixin.mp.bean;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;
import com.soecode.wxtools.util.xml.XStreamCDataConverter;
import com.soecode.wxtools.util.xml.XStreamTransformer;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;


/**
 * <pre>
 * 企业微信推送过来的消息，也是同步回复给用户的消息，xml格式
 * 相关字段的解释看微信开发者文档：
 * https://work.weixin.qq.com/api/doc#12977/%E4%BD%BF%E7%94%A8%E6%8E%A5%E6%94%B6%E6%B6%88%E6%81%AF

 * </pre>
 *
 * @author antgan
 */
@XStreamAlias("xml")
public class QyWxXmlMessage {

	///////////////////////
	// 以下都是企业微信推送过来的消息的xml的element所对应的属性
	///////////////////////

	@XStreamAlias("ToUserName")
	@XStreamConverter(value = XStreamCDataConverter.class)
	private String toUserName;


	@XStreamAlias("FromUserName")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String fromUserName;

	@XStreamAlias("CreateTime")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String createTime;

	@XStreamAlias("MsgType")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String msgType;

	@XStreamAlias("Event")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String event;

	@XStreamAlias("ChangeType")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String changeType;

	@XStreamAlias("UserID")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String userID;

	@XStreamAlias("NewUserID")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String newUserID;

	@XStreamAlias("Name")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String name;

	@XStreamAlias("Department")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String department;

	@XStreamAlias("Position")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String position;

	@XStreamAlias("Mobile")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String mobile;

	@XStreamAlias("Gender")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private int gender;

	@XStreamAlias("Email")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String email;

	@XStreamAlias("Status")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private int status;

	@XStreamAlias("Avatar")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String avatar;

	@XStreamAlias("EnglishName")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String englishName;

	@XStreamAlias("IsLeader")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private int isLeader;

	@XStreamAlias("Telephone")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private String telephone;

	@XStreamAlias("ExtAttr")
	@XStreamConverter(value = XStreamCDataConverter.class)
    private List<Item> extAttr;
	

	public String getToUserName() {
		return toUserName;
	}

	public void setToUserName(String toUserName) {
		this.toUserName = toUserName;
	}

	public String getFromUserName() {
		return fromUserName;
	}

	public void setFromUserName(String fromUserName) {
		this.fromUserName = fromUserName;
	}

	public String getCreateTime() {
		return createTime;
	}

	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	public String getMsgType() {
		return msgType;
	}

	public void setMsgType(String msgType) {
		this.msgType = msgType;
	}

	public String getEvent() {
		return event;
	}

	public void setEvent(String event) {
		this.event = event;
	}

	public String getChangeType() {
		return changeType;
	}

	public void setChangeType(String changeType) {
		this.changeType = changeType;
	}

	public String getUserID() {
		return userID;
	}

	public void setUserID(String userID) {
		this.userID = userID;
	}

	public String getNewUserID() {
		return newUserID;
	}

	public void setNewUserID(String newUserID) {
		this.newUserID = newUserID;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public int getGender() {
		return gender;
	}

	public void setGender(int gender) {
		this.gender = gender;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public String getAvatar() {
		return avatar;
	}

	public void setAvatar(String avatar) {
		this.avatar = avatar;
	}

	public String getEnglishName() {
		return englishName;
	}

	public void setEnglishName(String englishName) {
		this.englishName = englishName;
	}

	public int getIsLeader() {
		return isLeader;
	}

	public void setIsLeader(int isLeader) {
		this.isLeader = isLeader;
	}

	public String getTelephone() {
		return telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}

	public List<Item> getExtAttr() {
		return extAttr;
	}

	public void setExtAttr(List<Item> extAttr) {
		this.extAttr = extAttr;
	}


	protected static QyWxXmlMessage fromXml(String xml) {
		return XStreamTransformer.fromXml(QyWxXmlMessage.class, xml);
	}

	protected static QyWxXmlMessage fromXml(InputStream is) {
		return XStreamTransformer.fromXml(QyWxXmlMessage.class, is);
	}

	/**
	 * 密文转明文
	 *
	 * @param encryptedXml
	 * @param wxConfigStorage
	 * @param timestamp
	 * @param nonce
	 * @param msgSignature
	 * @return
	 * @throws AesException 
	 */
	public static QyWxXmlMessage decryptMsg(WXBizMsgCrypt cryptor, String encryptedXml,
			String timestamp, String nonce, String msgSignature) throws AesException {
		String plainText = cryptor.DecryptMsg(msgSignature, timestamp, nonce, encryptedXml);
		System.err.println("PlainText: " + plainText);
		return fromXml(plainText);
	}
	/**
	 * 密文转明文
	 * @param is
	 * @param wxConfig
	 * @param timestamp
	 * @param nonce
	 * @param msgSignature
	 * @return
	 * @throws AesException
	 */
	public static QyWxXmlMessage decryptMsg(WXBizMsgCrypt cryptor, InputStream is, String timestamp,
			String nonce, String msgSignature) throws AesException {
		try {
			return decryptMsg(cryptor, IOUtils.toString(is, "UTF-8"), timestamp, nonce, msgSignature);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}


	@Override
	public String toString() {
		return "QyWxXmlMessage [msgType=" + msgType + ", event=" + event + ", toUserName=" + toUserName + ", fromUserName=" + fromUserName + "]";
	}

	public static class Item {

		@XStreamAlias("Name")
		@XStreamConverter(value = XStreamCDataConverter.class)
	    private String name;

		@XStreamAlias("Value")
		@XStreamConverter(value = XStreamCDataConverter.class)
	    private String value;

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}
		
		protected static Item fromXml(String xml) {
			return XStreamTransformer.fromXml(Item.class, xml);
		}

		protected static Item fromXml(InputStream is) {
			return XStreamTransformer.fromXml(Item.class, is);
		}
	}
}
